/*********************************************************************
                         stuff for fingerprint window
written by IL
edited by CAS
7oct98 - most of this was in fpgen.c with highlighting stuff
*********************************************************************/
#include "fpp.h"
#include <gtk/gtkwidget.h>

extern int Altflag, Altbox;
extern int centreClone;
extern BOOL SCmarker;
extern int FpGelCBpicked;
extern GtkWidget *ctg_window;
extern void refresh_all_track_colors();
extern int cloneHigh();

void addclonetomarker(int cloneindex);
void displaymarker(void);
int getcolourbox(CLONE *clone);
#define MATCH 1
void requeetClone(char *temp);
void gelhighlight(void);

void redrawfingerprints()
{
  if(fpcolour || toler){
    if(graphActivate(g3)){
      drawfpdata(0);
    }
  }
}

/******************************************************
             DEF: fpclonehigh()
 called when a fingerprint is picked from fingerprint window
*******************************************************/
void fpclonehigh(int box)
{
  int i;
  struct contig *p;

  if (fpadd) return;
  if (box==0) return;

  for(i=0;i<FPMAX;i++)     
      if(box == indexbox[i]) break;

  if (i==FPMAX) return;

  if (fphigh==i) {
      displayclone(cloneindex[i]);
      return;
  }
  fphigh = i;
  /* fred 16.5.4 */
  if(merging){
    if((arrp(acedata,cloneindex[i],CLONE)->ctg == mergecontig1 ||
        arrp(acedata,cloneindex[i],CLONE)->ctg == mergecontig2) && 
        ctg_window!=NULL){
         for(p=root; p != NULL; p = p->new){
           if(p->next == cloneindex[i]){
               FpGelCBpicked=1;
               cloneHigh(p, 0);
               return;
            }  
         }
    }
  }
  else{
    if(arrp(acedata,cloneindex[i],CLONE)->ctg == currentctg && ctg_window!=NULL){
         for(p=root; p != NULL; p = p->new){
           if(p->next == cloneindex[i]){
               FpGelCBpicked=1;
               cloneHigh(p, 0);
               return;
            }  
         }
    }
  }
  /* cari 17.5.4 */
  if (ctg_window!=NULL) fphigh = i;
  gelhigh=cloneindex[i];
  gelhighlight();
}

void fingerPrint(int box)
/* this routine is picked from the menu and allows the user to add the clone */
/* picked to have it's finger print displayed in the finger print graph. */
{
  struct contig *p;
  BOOL last,found;

  p = root; 
  last = found = FALSE;

  while(!last){       
    if(p->box == box || p->chbox == box){    /* was picked is found */
      box = p->box;
      found = TRUE;
      break;
    }
    if(p->new==NULL)
      last = TRUE;
    p = p->new;
  } 
  if(!found){
    printf("ERROR could not find clone for box???\n");
    return;
  }
  addfp(p->next,0);
  if(bands)
    drawfpdata(1);                         /* redisplay the fp maps */
  graphPop();
}

void fpContig()
{
  struct contig *p;
  BOOL last;
  CLONE *clone;
 
  p = root;  
  last = FALSE;

  if(ctg_window==NULL)
    return; 
  while(!last){                         
    clone = arrp(acedata,p->next,CLONE);
    clone->selected = TRUE;
    if(p->new==NULL)
      last = TRUE;
    p = p->new;
  }
  refresh_all_track_colors();  /*fred 5/7/03*/
}

void fpclear()
/* clears the indexclone array hence clearing all fp maps */
/* and clears the graph graphically*/
{
  int i;

  for(i=0;i<FPMAX;i++){  
    cloneindex[i] = -1;
  }

  fphigh = -1;
  drawfpdata(0);

  FPYSHIFT = 0;           
  FPZOOM = 1.0;
  graphClear();            
  if(graphActivate(g4)){
    graphDestroy();
  }
  deletefp = FALSE;
  fpmove = FALSE;
  fpadd = FALSE;
}

void fpquit()
/* This routine clears the memory store on quitting */
{
  int i;

  for(i=0;i<FPMAX;i++){  
    cloneindex[i] = -1;
  }

  fphigh = -1;
  FPYSHIFT = 0;           
  FPZOOM = 1.0;            
  if(graphActivate(g4)){
    graphDestroy();
  }
  deletefp = FALSE;
  fpmove = FALSE;
  fpadd = FALSE;
  if(graphActivate(g3)){
    graphDestroy();
  }
}


void removefp(int box)
/* This function removes a map from the fp map display */
{
  int toremove=-1;
  int i;

  for(i=0;i<FPMAX;i++){     /* find the map corresponding to the map */
    if(box == indexbox[i]){
      toremove = i;        /* found it */
      break;
    }
  }
  if(toremove == fphigh)
    fphigh = -1;
  else if(fphigh > toremove)
    fphigh = fphigh - 1;
  for(i=0;i<FPMAX-1;i++){  /* remove it by moving the ones after it on top. */
    if(i >= toremove){
      cloneindex[i] = cloneindex[i+1];
      clonefpindex[i] = clonefpindex[i+1];
    }
  }
}

void mapmove(int box)
/* This routine is called by the pick menu function. Depending on wether or */
/* not certain flags are set different routines are called on picking */
{
  MAP_BOX = box;          
  if(box != 0){
    if(box == band)      
      graphBoxDrag(box, banddrag);
    else if(box == botscrollbox)
      graphBoxDrag(box, botscrolldrag);
    else if(box == fpcolourbox){
      fpcolour = !fpcolour;
      drawfpdata(0);
    }
    else if(box == Altbox){
      Altflag = !Altflag;
      drawfpdata(0);
    }
    else if(fpmove)      
      graphBoxDrag(box, mapdrag);
    else if(deletefp){      
      removefp(box);
      drawfpdata(0);
    }
    else if(box == tolerbox){
      toler = (!toler);
      drawfpdata(0);
    }
    else{
      fpclonehigh(box);
      drawfpdata(0); /* do not centre */
    }
  }
}

void mapdrag(float *x, float *y, BOOL isUp)
/* This controls the dragging of an fp  map. Y is constant */
{
  *y = FPBUTTONHEIGHT;
  if(isUp)
    { MAP_POS_X = *x;
     if(movecolomn(x))       /* if the map has been moved */ 
       drawfpdata(0);
    }
}

/************************************************************************
                     DEF: movecolomn
*************************************************************************/
BOOL movecolomn(float *x)
/* this routine returns TRUE if a fp move was successful and FALSE if */
/* the no change. i.e. dragged not enough to be moved to a new colomn*/
{
  int i;
  int startcol,fincol,numcol;
  int temp[FPMAX],fptemp[FPMAX];
  float col1,col2=-1,widthpercolomn;


  for(i=0;i<FPMAX;i++){    /* Initialise the tempory store */
    temp[i] = -1; 
  }

  startcol = fincol = -2;  /* set starting and finishing colomns to non obtainable results */
  for(i=fpcolstart;i<FPMAX;i++){ /* find the box that was picked and hence which colomn */
    if(MAP_BOX == indexbox[i]){
      startcol = i;
      break;
    }
  }
  numcol = -1;            /* find the number of colomns */
  for(i=0;i<FPMAX;i++){
    if(cloneindex[i] == -1){
      numcol = i;
      break;
    }
  }

   /* calculate the width of fp maps to enable the calculation of*/
   /* of where the map was dragged to */
  widthpercolomn = FPWIDTHPERCOLOMN;
  if(!SCmarker)
    col1 = FPSCALEWIDTH;
  else
    col1 =  FPSCALEWIDTH + (3*FPWIDTHPERCOLOMN);

  if(*x < col1)
    fincol = fpcolstart-1;
  else{
    for(i=fpcolstart;i<numcol;i++){
      col2 = col1 + widthpercolomn;
      if(*x > col1 && *x < col2){
	fincol = i;            /* This is where the dragging ended at colomn i */
	break;
      }
      col1 = col1 + widthpercolomn;
    }
    if (fincol == -2 && *x > col2) fincol = numcol-1;
  }
  if(startcol < 0 || fincol < -1 || numcol < 0 || startcol==fincol)
    return(FALSE);
     
  if(fincol < startcol)
	fincol = fincol +1;
  if (startcol < fincol){
	if(fphigh == startcol)
	  fphigh = fincol;
	else if(fphigh <= fincol && fphigh > startcol)
	  fphigh--;
  }
  else {
	if(fphigh == startcol)
	  fphigh = fincol;
	else if(fphigh >= fincol && fphigh < startcol)
	  fphigh++;
  }
  for(i=0;i<numcol;i++){ /* rearrange the colomn's i.e. change cloneindex */
	if(startcol < fincol){                /* if moving a colomn forward */
	  if(i < startcol){
	    temp[i] = cloneindex[i];
	    fptemp[i] = clonefpindex[i];
	  }
	  else if(i == fincol){
	    temp[i] = cloneindex[startcol];
	    fptemp[i] = clonefpindex[startcol];
	  }
	  else if(i < fincol){
	    temp[i] = cloneindex[i+1];
	    fptemp[i] = clonefpindex[i+1];
	  }
	  else{
	    temp[i] = cloneindex[i];
	    fptemp[i] = clonefpindex[i];
	  }
	}
	else{                               /* else if moving a colomn backwards */
	  if(i < fincol){
	    temp[i] = cloneindex[i];
	    fptemp[i] = clonefpindex[i];
	  }
	  else if(i == fincol){
	    temp[i] = cloneindex[startcol];
	    fptemp[i] = clonefpindex[startcol];
	  }
	  else if(i > fincol && i <= startcol){
	    temp[i] = cloneindex[i-1];
	    fptemp[i] = clonefpindex[i-1];
	  }
	  else{
	    temp[i] = cloneindex[i];
	    fptemp[i] = clonefpindex[i];
	  }
	}
   }/* end for */
   for(i=0;i<numcol;i++){ 
	cloneindex[i] = temp[i];
	clonefpindex[i] = fptemp[i];
   }
   return(TRUE); /* return TRUE i.e. a colomn wass moved */
}
void fpaddoption()
{
  if(fpadd){
    fpadd = FALSE;
    graphBoxDraw(fpaddbox,BLACK,WHITE);
  }
  else{
    fpadd = TRUE;
    fpmove = FALSE;
    deletefp = FALSE;
    graphBoxDraw(fpaddbox,BLACK,RED);
    graphBoxDraw(fpremovebox,BLACK,WHITE);
    graphBoxDraw(fpmovebox,BLACK,WHITE);
  }
  if(geladd){
    geladd = FALSE;
    if(graphActivate(gtest))
      graphBoxDraw(geladdbox,BLACK,WHITE);
  }
  if(fpflag){
    fpflag = FALSE;
    if(graphActivate(gselected))
      graphBoxDraw(fpflagbox,BLACK,WHITE);
  }
}

void fpmoveoption()
/* this routine sets the "mode" to move so that picking a map now causes */
/* the picking routine to call the drag/move options */
{

  if(fpmove){
    fpmove = FALSE;
    graphBoxDraw(fpmovebox,BLACK,WHITE);
  }
  else{
    fpmove = TRUE;
    deletefp = FALSE;
    fpadd = FALSE;
    graphBoxDraw(fpmovebox,BLACK,RED);
    graphBoxDraw(fpremovebox,BLACK,WHITE);
    graphBoxDraw(fpaddbox,BLACK,WHITE);
  }

}

void fpremove()
/* this routine sets the "mode" to remove so that picking a map now causes */
/* the picking routine to call the delete map routines */
{
  if(deletefp){
    deletefp = FALSE;
    graphBoxDraw(fpremovebox,BLACK,WHITE);
  }
  else{
    fpmove = FALSE;
    deletefp = TRUE;
    fpadd = FALSE;
    graphBoxDraw(fpremovebox,BLACK,RED);
    graphBoxDraw(fpmovebox,BLACK,WHITE);
    graphBoxDraw(fpaddbox,BLACK,WHITE);
  }

}

 void resetmode()
/* This routine sets the flags deletefp and fpmove to False so that */
/* deleting and moving the fp maps is not possible. and then kills the graph. */   
{
  deletefp = FALSE;
  fpmove = FALSE;
  fpflag = FALSE;
  graphDestroy();
}
